package us.gaaoc.framework.webapp.backingbeans.clerk;

import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.component.UISelectOne;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;

import us.gaaoc.framework.model.Attorney;
import us.gaaoc.framework.model.CaseRecord;
import us.gaaoc.framework.model.CaseRecordHistory;
import us.gaaoc.framework.model.CaseRecordIdExternalCaseRecordNumber;
import us.gaaoc.framework.model.CaseRecordStatus;
import us.gaaoc.framework.model.Counter;
import us.gaaoc.framework.model.CounterPerSigner;
import us.gaaoc.framework.model.Court;
import us.gaaoc.framework.model.CourtEvents;
import us.gaaoc.framework.model.CourtSeal;
import us.gaaoc.framework.model.DocumentStatus;
import us.gaaoc.framework.model.Documents;
import us.gaaoc.framework.model.LdapDirectoryPerson;
import us.gaaoc.framework.model.OrgParticipants;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.PersonParticipants;
import us.gaaoc.framework.model.Signatures;
import us.gaaoc.framework.model.constants.Constants;
import us.gaaoc.framework.signature.digital.DigitalSignerController;
import us.gaaoc.framework.signature.digital.SignatureValidator;
import us.gaaoc.framework.signature.visual.PDFStamper;
import us.gaaoc.framework.signature.visual.PDFStamperController;
import us.gaaoc.framework.util.DateUtil;
import us.gaaoc.framework.util.LocalCaseInformation;
import us.gaaoc.framework.util.io.FileUtility;
import us.gaaoc.framework.util.pdf.regexp.DocumentRegexps;
import us.gaaoc.framework.util.pdf.regexp.PDFRegexp;
import us.gaaoc.framework.util.pdf.regexp.PDFRegexpException;
import us.gaaoc.framework.webapp.backingbeans.BaseBackingBean;
import us.gaaoc.framework.webapp.util.Messages;

/**
 * 
 * @author hea
 * @date Apr 19, 2006
 * @version: GAJE 1.5
 * 
 */
@SuppressWarnings("unchecked")
public class CaseDetailsPage extends BaseBackingBean implements Serializable {

	private UIParameter documentClicked_Uploaded;
	
	public void setDocumentClicked_Uploaded(UIParameter documentClicked_Uploaded) {
		this.documentClicked_Uploaded = documentClicked_Uploaded;
	}


	public void setDocumentClicked_Imported(UIParameter documentClicked_Imported) {
		this.documentClicked_Imported = documentClicked_Imported;
	}

	private UIParameter documentClicked_Imported;

	
	/**
	 * 
	 */
	private static final long serialVersionUID = -679126909731124742L;

	private boolean validCase;
	
	/**
	 * Properties
	 */
	private CaseRecord caseRecord;

	private String caseRecordUuid;

	private String filerName;

	private boolean renderSignedText;

	private boolean renderSignButton;

	private Date courtDate, proposedCourtDate, originalCourtDate;

	/**
	 * to display the buttons on the case details page for various status
	 */
	private boolean renderImportButton;

	private boolean renderRejectButton;

	private boolean renderNegotiationButton;
	
	private boolean renderSignatureFailureMessage;

	private boolean renderCaseMetaData;
	
	/**
	 * Data Models for the personParticipants
	 */
	private DataModel initiatingPartyPersonModel;

	private DataModel defendentPartyPersonModel;

	private DataModel witnessPersonModel;

	private DataModel plantiffsAttorneyModel;

	private DataModel defendentsAttorneyModel;

	private DataModel initiatingPartyOrganizationDataModel;

	// private DataModel documentsModel;
	private DataModel importedDocumentsModel;

	private DataModel uploadedDocumentsModel;

	private List<Documents> importedDocumentsList;

	private List<Documents> uploadedDocumentsList;

	private boolean renderSetCourtDate = false;
	
	private static transient Logger LOG = Logger
			.getLogger(CaseDetailsPage.class);

	private String caseCaption;
	
	private String OCSSCaseNumber;
	
	private String courtCaseNumber;

	private List<Documents> documentList;

	private UIParameter validateBinding;

	private Documents bindDocument;

	private boolean validCourtSeal;

	private CourtSeal courtSeal;

	private String organizationName = null;

	// Frank added the rest
	private UIParameter signatureBinding;

	private DataModel signaturesListModel;

	private List<Signatures> signaturesList = new ArrayList<Signatures>();

	private DataModel sigantureCounterPerSignerModel;

	private CounterPerSigner signatureCounterPerSigner;

	private DataModel signatureCounterModel;

	private Counter signatureCounter;

	// private Documents signedDoc;

	private Documents docSignedByThisPerson;

	private String signatureConfTrackNumber;

	private String signatureTrackingID;

	private Documents signedDocument;

	private String jurisdiction;
	
	private DigitalSignerController digitalSignerController = new DigitalSignerController();
	private PDFStamperController pdfStamperController = new PDFStamperController();
	
	private boolean docNoContentsMessage = false;
	
	private boolean signatureFailedMessage = false;
	
	private boolean signatureFailed = false;
	
	private FacesMessage message;
	
	private boolean renderApplyCourtReceivedStampdButton = false;
	
	private boolean renderApplyDocketIdStampdButton = false;
	
	private boolean renderFileNewDocuments;

	private String courtUuid;
	
	/* Added for choosing judge*/
	private boolean renderJudge;

	private String judgeName;
	
	private ArrayList<SelectItem> judgesList;
	
	private UISelectOne judgeNameInput;
	
	//Code Added by Jogi
	
	private boolean renderRejectReasonButton;

	
	public boolean isRenderJudge() {
		return renderJudge;
	}

	public void setRenderJudge(boolean renderJudge) {
		this.renderJudge = renderJudge;
	}
	
	public String getJudgeName() {
		return judgeName;
	}


	public void setJudgeName(String judgeName) {
		this.judgeName = judgeName;
	}


	public ArrayList<SelectItem> getJudgesList() {
		judgesList = new ArrayList<SelectItem>();
		judgesList.add(new SelectItem("John H. Bailey","JELJHB")); // J
		judgesList.add(new SelectItem("Thomas H. Hodges","JHATLH")); //H
		judgesList.add(new SelectItem("Lindsay A. Tise","JFRLAT"));  //T
		judgesList.add(new SelectItem("Jeffery S. Malcom","JFRJSM")); //M
	    return judgesList;
	}


	public void setJudgesList(ArrayList<SelectItem> judgesList) {
		this.judgesList = judgesList;
	}


	public UISelectOne getJudgeNameInput() {
		return judgeNameInput;
	}


	public void setJudgeNameInput(UISelectOne judgeNameInput) {
		this.judgeNameInput = judgeNameInput;
	}
	
	
    /* End */
	
	/**
	 * Constructor
	 * 
	 */
	public CaseDetailsPage() {
		courtUuid = (String) this.getFacesContext().getExternalContext().getSessionMap().get("courtUuid");		
		String caseUuid = (String) this.getFacesContext().getExternalContext().getSessionMap().get("caseUuid");
		if(caseUuid!=null)
		this.loadData();
	}


	public boolean isRenderFileNewDocuments() {

		return renderFileNewDocuments;
	}

	/**
	 * Method to file new documents to existing case
	 */
	public String fileNewDocuments() {
		
		Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
		sessionMap.put("caseRecord", this.getCaseRecord());
		Person person = (Person) this.getFacesContext().getExternalContext().getSessionMap().get("person");
		String crUuid = (String) sessionMap.get("caseUuid");
		//CaseRecordStatus crs = this.getModelFacade().findCaseRecordStatusByCode(15);
		//this.getModelFacade().updateCaseRecordStatus(crUuid, crs);
		//this.getModelFacade().addCaseRecordHistory(crUuid, 13, person);  //Filing Readied For Addition
					// re-add to fix issue:
		//  b7006e6c-695c-11dd-945f-00301b45ff56
		// commit the transaction
		//HibernatePhaseListener.getSessionFactory().getCurrentSession()
		//   .getTransaction().commit();
		//  		HibernatePhaseListener.getSessionFactory().getCurrentSession()
		 //  .getTransaction().begin();
		  
		//-----------------
		sessionMap.put("externalCaseCategoryCode",this.getCaseRecord().getCaseRecordAction().getId());

		String toString = "fileNewDocuments";
		return toString;
	}
	
	boolean renderUpdateCourtCaseNumber = false;
	
	public boolean isRenderUpdateCourtCaseNumber() {
		return renderUpdateCourtCaseNumber;
	}
	
	public void setRenderUpdateCourtCaseNumber(
			boolean renderUpdateCourtCaseNumber) {
		this.renderUpdateCourtCaseNumber = renderUpdateCourtCaseNumber;
	}
	
	public boolean calculateRenderUpdateCourtCaseNumber(){
		Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
		String crUuid = (String) sessionMap.get("caseUuid");
		CaseRecord c = this.getModelFacade().findCaseRecordById(crUuid,courtUuid);
		
		if(c.getStatus().getCode() != Constants.CaseRecordStatus.IMPORTED)
		{
			return true;
		}
		
		return false;
	}
	
	/**
	 * Method to set court case number.
	 */
	public void updateCourtCaseNumber(){
		Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
		String crUuid = (String) sessionMap.get("caseUuid");
		CaseRecord c = this.getModelFacade().findCaseRecordById(crUuid,courtUuid);
			this.getModelFacade().updateCaseRecordCourtTrackingID(crUuid, this.courtCaseNumber, courtUuid);
	}
	
	public boolean isRsenderUpdateCourtCaseNumber()
	{
		Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
		String crUuid = (String) sessionMap.get("caseUuid");
		CaseRecord c = this.getModelFacade().findCaseRecordById(crUuid,courtUuid);
		
		if(c.getStatus().getCode() != Constants.CaseRecordStatus.IMPORTED)
		{
			if(c.getCourt().getUuid().equals("courtUuidCrawford") ||
			   c.getCourt().getUuid().equals("courtUuidFranklin"))
					return true;
		}
		
		return false;
	}
	
	/**
	 * This method loads data from the database
	 * 
	 */
	private void loadData() {
		
		validCase = true;
		
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String courtUuid = (String) sessionMap.get("courtUuid");
		Court court = this.getModelFacade().findCourt(courtUuid);
		try {
			this.setJurisdiction(LocalCaseInformation.getJurisdiction(courtUuid));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


		String caseUuid = (String) sessionMap.get("caseUuid");

		this.setCaseRecordUuid(caseUuid);

		CaseRecord c = (CaseRecord) this.getModelFacade().findCaseRecordById(
				caseUuid, courtUuid);

	//TODO: evaluate of clarke only section is needed
//		if(courtUuid.equalsIgnoreCase(Constants.Courts.ClarkeCounty))
	//	{
			if(court.isThruClerksAuthority() || c.getStatus().getCode() == Constants.CaseRecordStatus.QUEUED_FOR_IMPORT)
			{
				this.setRenderSetCourtDate(false);
			}
			else
			{
				this.setRenderSetCourtDate(true);
			}
		//}

		
		this.setCaseRecord(c);
		
		Person personSigned = (Person) this.getFacesContext()
				.getExternalContext().getSessionMap().get("person");

//b7006e6c-695c-11dd-945f-00301b45ff56

		Hibernate.initialize(c.getPersonParticipants());
		Hibernate.initialize(c.getOrgParticipants());
		Hibernate.initialize(c.getDocuments());
		Hibernate.initialize(c.getLocalCaseCategory());
		Hibernate.initialize(c.getLocalCaseDivision());
		Hibernate.initialize(c.getLocalCaseFilingType());
		Hibernate.initialize(c.getLocalCaseType());

		for (int i = 0; i < c.getPersonParticipants().size(); i++) {
			Hibernate.initialize(
					c.getPersonParticipants().get(i).getPerson()
					.getAddresses()
					);
		}
		for (int i = 0; i < c.getOrgParticipants().size(); i++) {
			Hibernate.initialize(
					c.getOrgParticipants().get(i)
					.getOrganizations().getAddresses()
					);
		}
		
		/*
		 * for(Documents doc: c.getDocuments()) {
		 * Hibernate.initialize(doc.getCourtSeal()); }
		 */
		for (int i = 0; i < c.getDocuments().size(); i++) {
			Hibernate.initialize(
					c.getDocuments().get(i).getDocumentInstance()
					);
		}

		List<PersonParticipants> pParticipantsList = c.getPersonParticipants();
		List<OrgParticipants> oParticipantsList = c.getOrgParticipants();

		int statusCode = c.getStatus().getCode();

		List initiatingPartyOrganizationList = new ArrayList();

		// for initiating party person list
		List initiatingPartyPersonList = new ArrayList();

		// for defendant party person list
		List defendentPartyPersonList = new ArrayList();

		// for witness person list
		List witnessPersonList = new ArrayList();

		// for plantiff's Attorneys
		List plantiffsAttorneyList = new ArrayList();

		// for defendent's Attorneys
		List defendentsAttorneyList = new ArrayList();

		for (OrgParticipants o : oParticipantsList) {
			if (o.getRelationship().getCode() == 1)
				initiatingPartyOrganizationList.add(o);
		}

	
		
		PersonParticipants kcr = null; 
		for (PersonParticipants o : pParticipantsList) {
			if (o.getRelationship().getCode() == 1)
				initiatingPartyPersonList.add(o);
			else if (o.getRelationship().getCode() == 2)
				defendentPartyPersonList.add(o);
			else if (o.getRelationship().getCode() == 3)
				witnessPersonList.add(o);
			else if (o.getRelationship().getCode() == 4 && !o.getPerson().getFirstName().equalsIgnoreCase("ff20da2c-8e5c-11dd-9b78-0016d3"))
			{
				String barID = this.getModelFacade().getBarID(o.getPerson(), court);
				if (barID.equals("597910")) { 
					kcr = o;
				}
				Attorney a = new Attorney();
				a.setBarID(this.getModelFacade().getBarID(o.getPerson(), court));
				a.setPerson(o.getPerson());
				o.getPerson().setAttorney(a);
				plantiffsAttorneyList.add(o);
			}
			else if (o.getRelationship().getCode() == 5)
				defendentsAttorneyList.add(o);
			else if (o.getRelationship().getCode() == 6) {
				Person filer = o.getPerson();
				this.setFilerName(filer.getFirstName() + " "
						+ filer.getMiddleName() + " " + filer.getLastName());
			}
		}
		//The following block is for Fulton's SAAG office Kathryn C. Reeder
		if(courtUuid.equalsIgnoreCase("courtUuid4"))
		{
			Person person = this.getModelFacade().findAttorneyByBarIDAndOrgAsPerson("597910", "initiatingPartyOrganizationUuid4");
			if(person != null) {
				List<PersonParticipants> ppList = this.getModelFacade().getPersonParticipantByPerson(person);
				if (!ppList.isEmpty() && this.getModelFacade().getPersonParicipant(c).contains(person)){
					plantiffsAttorneyList.clear();
					plantiffsAttorneyList.add(kcr);
				}
			}
		}
		//End
		initiatingPartyOrganizationDataModel = new ListDataModel();
		initiatingPartyOrganizationDataModel
				.setWrappedData(initiatingPartyOrganizationList);

		initiatingPartyPersonModel = new ListDataModel();
		initiatingPartyPersonModel.setWrappedData(initiatingPartyPersonList);

		defendentPartyPersonModel = new ListDataModel();
		defendentPartyPersonModel.setWrappedData(defendentPartyPersonList);

		witnessPersonModel = new ListDataModel();
		witnessPersonModel.setWrappedData(witnessPersonList);

		defendentsAttorneyModel = new ListDataModel();
		defendentsAttorneyModel.setWrappedData(defendentsAttorneyList);

		plantiffsAttorneyModel = new ListDataModel();
		plantiffsAttorneyModel.setWrappedData(plantiffsAttorneyList);

		List<Documents> pdfList = new ArrayList<Documents>();
		// List<Documents> xmlList = new ArrayList<Documents>();
		// List<Documents> xslList = new ArrayList<Documents>();
		List<Documents> iDoc = new ArrayList<Documents>();
		List<Documents> uDoc = new ArrayList<Documents>();

		boolean docOrder = false;
		boolean docSigned = false;

		pdfList = this.getModelFacade().getPDFDocuments(caseUuid);
        //added by Michael A to get the list of pdf's signed by both the attorney and the clerk or not, to display 
		for (Documents document : pdfList) {
			int docStatusCode = document.getStatus().getCode();
			if (docStatusCode == 2) {			//imported documents
				iDoc.add(document);
			} else if (docStatusCode != 2) {
				uDoc.add(document);
			}
		}
		// Frank added the following block
		for (Documents doc : uDoc) {
			
			docOrder = digitalSignerController.isDocumentOrderForClerk(doc);
			docSigned = digitalSignerController.isDocumentSignedForClerk(doc, personSigned);
			if (docOrder) {
				doc.setOrderedDoc(true);
				if (docSigned) {
					//this.renderSignedText = true;
					//this.renderSignButton = false;
					doc.setSignedDoc(true);
					
				} else {
					//this.renderSignedText = false;
					//this.renderSignButton = true;
					doc.setSignedDoc(false);
				}
			}else{
				doc.setOrderedDoc(false);
			}
		}
		
		if ((statusCode != 2) && (statusCode != 6) && (statusCode != 3)) {
			this.setRenderImportButton(true);
			this.setRenderRejectButton(true);
		} else if ((statusCode == 2) || (statusCode == 3)) { // Imported or
																// Rejected
			this.renderApplyCourtReceivedStampdButton = true;
			this.renderApplyDocketIdStampdButton = true;
			this.setRenderImportButton(false);
			this.setRenderRejectButton(false);
		}
		
		if (courtUuid.equalsIgnoreCase("courtUuid5") && (statusCode != 2) && (statusCode != 6) && (statusCode != 3)){
			this.setRenderJudge(true);
		}		
		
		if ((statusCode == 1)				//Received	
				|| (statusCode == 13)) {	//ReceivedFromJudge
			this.updateDatabaseAfterAllSigned(uDoc, personSigned);
		}
		
		if (statusCode == 21) {  //QueuedForImport
			this.setRenderImportButton(false);
		}
		
		if (pdfList.size() > 0) {
			this.setDocumentList(pdfList);
		} 
		
		this.setDocumentList(pdfList);
		this.setImportedDocumentsList(iDoc);
		this.setUploadedDocumentsList(uDoc);

		importedDocumentsModel = new ListDataModel();
		uploadedDocumentsModel = new ListDataModel();

		importedDocumentsModel.setWrappedData(this.getImportedDocumentsList());
		uploadedDocumentsModel.setWrappedData(this.getUploadedDocumentsList());

		/*
		// for court date negotiation -- for web services
		CourtHearingNegotiations chn = this.getModelFacade().findCourtHearingNegotiationsByCaseRecordUuid(caseUuid);
			if (chn != null) {
				this.setRenderNegotiationButton(true);
				this.setOriginalCourtDate(chn.getPreviousCourtDate());
				this.setProposedCourtDate(chn.getProposedCourtDate());
			}
			// End for web service
			*/
			// for court date negotiation -- for Douglas county: courtUuid3
			if (courtUuid.equals("courtUuid3")) {
				this.setRenderNegotiationButton(true);
			}
			
			/*
			 * Edited by Jogi
			 * 
			 * 
			 * If the case status is any of the following codes,
			 * the reject button should be rendered:
			 * 
			 *  3 - Rejected
			 * 10 - SentToAttorney
			 * 11 - ReadyToSendToCourt
			 * 16 - SentToAttorneyAddition
			 * 19 - RejectedByJudge
			 */		
			if (statusCode == 3 
				|| statusCode == 19 
				|| statusCode == 10
				|| statusCode == 11
				|| statusCode == 16) {
				this.setRenderRejectReasonButton(true);
			}

		// set court date
		this.setCourtDate(this.getModelFacade().findCourtDate(caseUuid));
		// set case caption
		
		if(c.getCaseRecordAction().getId()==3){

			if( !initiatingPartyOrganizationList.isEmpty() && !defendentPartyPersonList.isEmpty() )
			{
				String initiatingPartyOrgName = ((OrgParticipants) initiatingPartyOrganizationList
						.get(0)).getOrganizations().getName();
				Person defendent = ((PersonParticipants) defendentPartyPersonList
						.get(0)).getPerson();
				String defendentName = defendent.getFirstName() + " "
						+ defendent.getMiddleName() + " "
						+ defendent.getLastName();
				String etal = "";
			
				String PcaseCaption = String.format("DHS/%s vs %s",etal,defendentName);
				
				this.setCaseCaption(PcaseCaption);
			}
			else{
				//CASE IS INVALID
				this.setCaseCaption("DHS/INVALID CASE");
				validCase = false;
			}
			
		
		}
		
		
		else{
		if ( !initiatingPartyOrganizationList.isEmpty() &&  !initiatingPartyPersonList.isEmpty() &&  !defendentPartyPersonList.isEmpty())
		 {
			String initiatingPartyOrgName = ((OrgParticipants) initiatingPartyOrganizationList
					.get(0)).getOrganizations().getName();
			Person defendent = ((PersonParticipants) defendentPartyPersonList
					.get(0)).getPerson();
			String defendentName = defendent.getFirstName() + " "
					+ defendent.getMiddleName() + " "
					+ defendent.getLastName();
			String etal = "";
			if(initiatingPartyPersonList.size() > 1)
			{
				etal = " et. al.";
			}
			String PcaseCaption = String.format("DHS/%s vs %s",								
					((PersonParticipants)initiatingPartyPersonList.get(0)).getPerson().getFirstName() + " " + 
					((PersonParticipants)initiatingPartyPersonList.get(0)).getPerson().getLastName() + etal,						
					defendentName);
			
			this.setCaseCaption(PcaseCaption);
		}else{
			//CASE IS INVALID
			this.setCaseCaption("DHS/INVALID CASE");
			validCase = false;
		}
		
	}
		
		//set OCSS case number
		List<CaseRecordIdExternalCaseRecordNumber> externalCaseIds = 
		    this.getModelFacade().findExternalCaseRecordNumbers(caseUuid);
		if (!externalCaseIds.isEmpty()) {
		    // TODO Need to have types to classify the external 
		    // identifiers
		    CaseRecordIdExternalCaseRecordNumber externalCaseId = externalCaseIds.get(0);
		    String externalCaseNumber = externalCaseId.getExternalCaseRecordNumber();
		    this.setOCSSCaseNumber(externalCaseNumber);
		}
		/*
		String fromPage = (String) sessionMap.get("from");
		if ((fromPage.equalsIgnoreCase("searchPage") || (fromPage.equalsIgnoreCase("attFilingsTablesPage")) ||
				fromPage.equalsIgnoreCase("allFilingsTablesPage")) && 
				((statusCode == 2) || (statusCode == 1) || (statusCode == 20) || (statusCode == 6))) {
				// GAJETWOX-137: disposed cases need a new filing button also
			this.setRenderFileNewDocuments(true);
		}
		*/
		if(court.isThruClerksAuthority())
		{
			this.setRenderFileNewDocuments(false);
		}else
		{
		this.setRenderFileNewDocuments(true);
		}
		
		
		//set court case number(docketID)
		String docketID = c.getCaseTrackingId();
		this.setCourtCaseNumber(docketID);
		
		if(getCaseRecord().getCaseTrackingId() == null ||
			getCaseRecord().getCaseTrackingId().trim().length() == 0)
		{
			this.setRenderCaseMetaData(false);
		}else if(courtUuid.equalsIgnoreCase("courtUuid3")){
			this.setRenderCaseMetaData(true);
		}
		
		this.setRenderUpdateCourtCaseNumber(this.calculateRenderUpdateCourtCaseNumber());
		
		
		if(!this.validCase)
		{
			this.setRenderUpdateCourtCaseNumber(false);
			this.setRenderCaseMetaData(false);
			this.setRenderApplyCourtReceivedStampdButton(false);
			this.setRenderImportButton(false);
			this.setRenderJudge(false);
		}
		
		
		
	}
	
	private String courtRoom;
	private String courtTime;
	
	public static String padLeft(int size, String ch, String str)
	{
		String ret = str;
		while(ret.length() <= size)
		{
			ret = ch + ret;
		}
		return ret;
	}
	
	public String submitMetaData() throws PDFRegexpException
	{
		System.out.println(courtRoom);
		System.out.println(courtTime);
		
		Person personSigned = (Person) this.getFacesContext()
				.getExternalContext().getSessionMap().get("person");
		
		String courtUuid = (String)this.getFacesContext().getExternalContext().getSessionMap().get("courtUuid");
		String clerkRoleUuid = "uuid2"; // The Clerk Role UUID
		for (Documents doc : documentList) {
			if(doc.getStatus().getCode() != 2)
			{
				int docInstanceCode = doc.getDocumentInstance().getCode();
			
				if ((docInstanceCode == 197) || (docInstanceCode == 196)) 
				{
					PDFStamperController pdfStamper = new PDFStamperController();
					Map<String,String> targets  = new java.util.HashMap<String,String>();
					String regexp = DocumentRegexps.getRegexp(docInstanceCode, DocumentRegexps.COURT_META_DATA);
					if(proposedCourtDate != null)
					{
						Calendar cal = new GregorianCalendar();
						cal.setTime(proposedCourtDate);
						targets.put("COURT_DAY",Integer.toString(cal.get(Calendar.DAY_OF_MONTH)));
						targets.put("COURT_MONTH_YEAR",
								cal.getDisplayName(Calendar.MONTH,Calendar.LONG,java.util.Locale.ENGLISH) + ", " +
								Integer.toString(cal.get(Calendar.YEAR)).substring(0, 4));						
					}
					if(courtRoom != null)
					{							
						// We pad the court room so that it doesn't merge into the prose
						targets.put("COURT_ROOM",padLeft(1," ",courtRoom));						
					}
					if(courtTime != null)
					{
						targets.put("COURT_TIME",courtTime);					
					}
					try{
						pdfStamper.applyRegexpOnDocument(doc, personSigned, clerkRoleUuid, courtUuid, targets, regexp,-1);
					}catch(PDFRegexpException exn)
					{
						//fallback to old visual mark lookups
						pdfStamper.addCourtDateOnDocument(doc, personSigned, clerkRoleUuid, courtUuid, proposedCourtDate);
						pdfStamper.addCourtNumberOnDocument(doc, personSigned, clerkRoleUuid, courtUuid, courtRoom);
						pdfStamper.addCourtTimeOnDocument(doc, personSigned, clerkRoleUuid, courtUuid, courtTime);
					}
				}
			}
		}
		
		return "gotoImportFiling";
	}

	/**
	 * Getter for property renderNegotiationButton
	 * 
	 * @return renderNegotiationButton
	 */
	public boolean isRenderNegotiationButton() {
		return renderNegotiationButton;
	}

	/**
	 * Setter for property renderNegotiationButton
	 * 
	 * @param renderNegotiationButton
	 */
	public void setRenderNegotiationButton(boolean renderNegotiationButton) {
		this.renderNegotiationButton = renderNegotiationButton;
	}

	/**
	 * Getter for property renderImportButton
	 * 
	 * @return renderImportButton
	 */
	public boolean isRenderImportButton() {
		return renderImportButton;
	}

	/**
	 * Setter for property renderImportButton
	 * 
	 * @param renderImportButton
	 */
	public void setRenderImportButton(boolean renderImportButton) {
		this.renderImportButton = renderImportButton;
	}

	/**
	 * Getter for property renderRejectButton
	 * 
	 * @return renderRejectButton
	 */
	public boolean isRenderRejectButton() {
		return renderRejectButton;
	}

	/**
	 * Setter for property renderRejectButton
	 * 
	 * @param renderRejectButton
	 */
	public void setRenderRejectButton(boolean renderRejectButton) {
		this.renderRejectButton = renderRejectButton;
	}

	/**
	 * This method navigates user to the Import Filing Page
	 * 
	 * @return String
	 */
	public String gotoImportFiling() {
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		sessionMap.put("caseUuid", this.getCaseRecordUuid());
		//To add judge to the session
		String judge = (String)this.getJudgeNameInput().getValue();
		this.getFacesContext().getExternalContext().getSessionMap().put("judge", judge);
		String judgeTest = (String)this.getFacesContext().getExternalContext().getSessionMap().get("judge");
		return "gotoImportFiling";
	}

	/**
	 * This method navigates user to the Reject Filing Page
	 * 
	 * @return String
	 */
	public String gotoRejectFiling() {
		Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();		
		sessionMap.put("caseUuid", this.getCaseRecordUuid());
		return "gotoRejectFiling";
	}

	/**
	 * This method navigates user to the previous page
	 * 
	 * @return String
	 */
	public String back() {
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String fromPage = (String) sessionMap.get("from");
		sessionMap.remove("from");
		sessionMap.remove("caseUuid");
		sessionMap.remove("clerkCaseDetailsPage");

		if (fromPage.equalsIgnoreCase("ChildEnforcementCaseTypePage")) {
			return "childEnforcement";
		} else if (fromPage.equalsIgnoreCase("ReceivedFilingPage")) {
			return "received";
		} else if (fromPage.equalsIgnoreCase("RejectedFilingPage")) {
			return "rejected";
		} else if (fromPage.equalsIgnoreCase("ImportedFilingPage")) {
			return "imported";
		} else if (fromPage.equalsIgnoreCase("DisposedFilingPage")) {
			return "disposed";
		} else if (fromPage.equalsIgnoreCase("TransmissionErrorFilingPage")) {
			return "transmissionError";
		} else if (fromPage.equalsIgnoreCase("ServedFilingPage")) {
			return "served";
		} else if (fromPage.equalsIgnoreCase("NonServedFilingPage")) {
			return "served";
		} else if (fromPage.equalsIgnoreCase("NewFilingPage")) {
			return "newFiling";
		} else if (fromPage.equalsIgnoreCase("AppellateCaseTypePage"))
			return "appellate";
		else if (fromPage.equalsIgnoreCase("CivilCaseTypePage"))
			return "civil";
		else if (fromPage.equalsIgnoreCase("childSupportTrashCanPage"))
			return "childSupportTrashCanPage";
		else if (fromPage.equalsIgnoreCase("SearchBeanPage"))
			return "searchResultPage";
		else if (fromPage.equalsIgnoreCase("clerkMainPage")) 
			return "gotoMainPage";
		else if (fromPage.equalsIgnoreCase("MainPage"))
			return "gotoMainPage";
		else if (fromPage.equalsIgnoreCase("searchPage")){
            sessionMap.put("from", "clerkMainPage");
            return "searchPage";
		}else
			return "";

	}

/*	/**
	 * This method navigates user to the Accept Confirmation Page
	 * 
	 * @return String
	 */
/*	public String acceptNegotiatedCourtDate() {
		return "gotoAcceptConfirmationPage";
	}*/

	/**
	 * This method navigates user to the Reject Confirmation Page
	 * 
	 * @return String
	 */
/*	public String rejectNegotiatedCourtDate() {
		return "gotoRejectConfirmationPage";
	}*/

	
	/**
	 * Getter for property courtDate
	 * 
	 * @return courtDate
	 */
	public Date getCourtDate() {
		return courtDate;
	}

	/**
	 * Setter for property courtDate
	 * 
	 * @param courtDate
	 */
	public void setCourtDate(Date courtDate) {
		this.courtDate = courtDate;
	}

	/**
	 * Getter for property proposedCourtDate
	 * 
	 * @return proposedCourtDate
	 */
	public Date getProposedCourtDate() {
		return this.proposedCourtDate;
	}

	/**
	 * Setter for property proposedCourtDate
	 * 
	 * @param proposedCourtDate
	 */
	public void setProposedCourtDate(Date proposedCourtDate) {
		this.proposedCourtDate = proposedCourtDate;
	}

	/**
	 * Getter for originalCourtDate
	 * 
	 * @return originalCourtDate
	 */
	public Date getOriginalCourtDate() {
		return this.originalCourtDate;
	}

	/**
	 * Setter for property originalCourtDate
	 * 
	 * @param originalCourtDate
	 */
	public void setOriginalCourtDate(Date originalCourtDate) {
		this.originalCourtDate = originalCourtDate;
	}

	/**
	 * @param initiatingPartyOrganizationDataModel
	 *            The initiatingPartyOrganizationDataModel to set.
	 */
	public void setInitiatingPartyOrganizationDataModel(
			DataModel initiatingPartyOrganizationDataModel) {
		this.initiatingPartyOrganizationDataModel = initiatingPartyOrganizationDataModel;
	}
	
	public String submitCourtDate() {
		//Start the transaction
		// b7006e6c-695c-11dd-945f-00301b45ff56
		//HibernatePhaseListener.getSessionFactory().getCurrentSession()
		//	.getTransaction().begin();
		
		Person personLoggingin = (Person) this.getFacesContext()
			.getExternalContext().getSessionMap().get("person");
		String updatePersonUuid = personLoggingin.getUuid();
		this.getModelFacade().updateCourtDate(this.getCaseRecord().getUuid(),
				this.getProposedCourtDate(), updatePersonUuid);
		//Frank added the following block to track the caseRecord
		
		
		CaseRecordHistory crh = new CaseRecordHistory();
		crh.setCaseRecord(caseRecord);
		crh.setEventType(this.getModelFacade().findCaseRecordEventType(22));
		crh.setEventDateTime(DateUtil.getCurrentDate());
		crh.setPerson(personLoggingin);
		this.getModelFacade().insertCaseRecordHistory(crh);

		//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().commit();
	//End 
		
		//Added by Frank to put court date onto Rule NISI
			for (Documents doc : documentList) {
				int docTypeCode = doc.getDocumentInstance().getDocumentType().getCode();
				int docStatusCode = doc.getStatus().getCode();
				if ((docTypeCode == 27) 
						&& (docStatusCode == 1 
						|| docStatusCode == 4 
						|| docStatusCode == 6
						|| docStatusCode == 11) ) {
					
					PDFStamper pdfStamper = new PDFStamper();
					String targetForAttorneySignedDate = "+";
					byte[] newContent = pdfStamper.addDate(doc, this.getProposedCourtDate(),
						targetForAttorneySignedDate);
					if (newContent != null) {
					    doc.setContent(null,newContent);
					} else {
					    LOG.debug("Court Date target not " +
					    		"found in document. " +
					    		"Contents Unchanged.");
					}
				}
			}
		//End	
			
		// commit the transaction
		// b7006e6c-695c-11dd-945f-00301b45ff56
		//HibernatePhaseListener.getSessionFactory().getCurrentSession()
		//	.getTransaction().commit();
		return "stayWithRedirect";
	}

	public void validateDate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException, Exception {
		java.util.Date newValue = (java.util.Date) value;

		/*
		 * There is a bug in jsf page to pass over a date value, the passed
		 * value is always 1 day behind . The day field of the Calendar object
		 * starts with 1 but the month field starts with 0. This confusion might
		 * be the cause of the bug.
		 */
		Calendar c = new GregorianCalendar();
		c.setTime(newValue);

		System.out.println("Month = " + c.get(Calendar.MONTH));
		System.out.println("Date = " + c.get(Calendar.DATE));

		int date = c.get(Calendar.DATE);
		c.set(Calendar.DATE, date + 1);
		newValue = c.getTime();

		if (!isValidDate(newValue)) {
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(message);
		}
	}
	/** 
     * Method to check date to ensure that it is not a future date. 
     */
	protected boolean isValidDate(java.util.Date value) throws Exception {
		boolean validField = false;
		if (value.compareTo(DateUtil.getCurrentDate()) < 0) {
			validField = false;
			message = Messages.getMessage(
					"us.gaaoc.framework.webapp.util.errorMessage",
					"incorrectDate", null);
			message.setDetail(message.getDetail());
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
		} else {
			validField = true;
		}
		return validField;
	}

	
	/**
	 * @return Returns the caseRecord.
	 */
	public CaseRecord getCaseRecord() {
		return caseRecord;
	}

	/**
	 * Setter for property caseRecord
	 * 
	 * @param caseRecord
	 */
	public void setCaseRecord(CaseRecord caseRecord) {
		this.caseRecord = caseRecord;
	}

	/**
	 * Getter for property filerName
	 * 
	 * @return filerName
	 */
	public String getFilerName() {
		return filerName;
	}

	/**
	 * Setter for property filer
	 * 
	 * @param filerName
	 */
	public void setFilerName(String filerName) {
		this.filerName = filerName;
	}

	/**
	 * Getter for property defendentPartyPersonModel
	 * 
	 * @return defendentPartyPersonModel
	 */
	public DataModel getDefendentPartyPersonModel() {
		return defendentPartyPersonModel;
	}

	/**
	 * Setter for property defendentPartyPersonModel
	 * 
	 * @param defendentPartyPersonModel
	 */
	public void setDefendentPartyPersonModel(DataModel defendentPartyPersonModel) {
		this.defendentPartyPersonModel = defendentPartyPersonModel;
	}

	/**
	 * Getter for property defendentsAttorneyModel
	 * 
	 * @return defendentsAttorneyModel
	 */
	public DataModel getDefendentsAttorneyModel() {
		return defendentsAttorneyModel;
	}

	/**
	 * Setter for property defendentAttorneyModel
	 * 
	 * @param defendentsAttorneyModel
	 */
	public void setDefendentsAttorneyModel(DataModel defendentsAttorneyModel) {
		this.defendentsAttorneyModel = defendentsAttorneyModel;
	}

	/**
	 * Getter for property initaingPartyPersonModel
	 * 
	 * @return initaingPartyPersonModel
	 */
	public DataModel getInitiatingPartyPersonModel() {
		return initiatingPartyPersonModel;
	}

	/**
	 * Setter for property initiatingPartyPersonModel
	 * 
	 * @param initiatingPartyPersonModel
	 */
	public void setInitiatingPartyPersonModel(
			DataModel initiatingPartyPersonModel) {
		this.initiatingPartyPersonModel = initiatingPartyPersonModel;
	}

	/**
	 * Getter for property initatingPartyOrganizationModel
	 * 
	 * @return initiatingPartyOrganizationModel
	 */
	public DataModel getInitiatingPartyOrganizationDataModel() {
		return initiatingPartyOrganizationDataModel;
	}

	/**
	 * Getter for property witnessPersonModel
	 * 
	 * @return witnessPersonModel
	 */
	public DataModel getWitnessPersonModel() {
		return witnessPersonModel;
	}

	/**
	 * Setter for property witnessPersonModel
	 * 
	 * @param witnessPersonModel
	 */
	public void setWitnessPersonModel(DataModel witnessPersonModel) {
		this.witnessPersonModel = witnessPersonModel;
	}

	/**
	 * Getter for property plantiffsAttorneyModel
	 * 
	 * @return plantiffsAttorneyModel
	 */
	public DataModel getPlantiffsAttorneyModel() {
		return plantiffsAttorneyModel;
	}

	/**
	 * Setter for property plantiffsAttorneyModel
	 * 
	 * @param plantiffsAttorneyModel
	 */
	public void setPlantiffsAttorneyModel(DataModel plantiffsAttorneyModel) {
		this.plantiffsAttorneyModel = plantiffsAttorneyModel;
	}

	/**
	 * Getter for property caseCaption
	 * 
	 * @return caseCaption
	 */
	public String getCaseCaption() {
		return caseCaption;
	}

	/**
	 * Setter for property caseCaption
	 * 
	 * @param caseCaption
	 */
	public void setCaseCaption(String caseCaption) {
		this.caseCaption = caseCaption;
	}

	/**
	 * @return courtSeal
	 */
	public CourtSeal getCourtSeal() {
		return courtSeal;
	}

	/**
	 * sets courtSeal
	 * 
	 * @param courtSeal
	 */
	public void setCourtSeal(CourtSeal courtSeal) {
		this.courtSeal = courtSeal;
	}

	/**
	 * This method gets called when user wants to view the PDF/XML Docuement
	 * 
	 * @return String
	 */

	// this method need to modification. session return null string
	/*
	public String viewFile() {
		Map requestMap = this.getFacesContext().getExternalContext()
				.getRequestParameterMap();
		HttpServletResponse resp = (HttpServletResponse) this.getFacesContext()
				.getExternalContext().getResponse();
		String docTitle = (String) requestMap.get("title");

		byte[] docContent = null;
		for (Documents doc : this.getDocumentList()) {
			if (doc.getTitle().equalsIgnoreCase(docTitle)) {
				docContent = doc.getContent();
				break;
			}
		}
		try {
			FileUtility.streamReportToBrowser(resp, docTitle, docContent);
		} catch (IOException e) {
			LOG.error("Error in CaseDetailPage.viewFile() method: " + e);
		}
		this.getFacesContext().responseComplete();
		return "stay";
	}
	*/
	// this method need to modification. session return null string
	public void viewFile() {
		Documents docUploaded = (Documents) this.getDocumentClicked_Uploaded().getValue();
		Documents docImported = (Documents) this.getDocumentClicked_Imported().getValue();
		Documents docToStream = docUploaded;
		
		if (docToStream == null) { // If the uploaded doc is null, try others
			docToStream = docImported;
		} 
		
		if (docToStream != null) {
			FacesContext context = this.getFacesContext();
			HttpServletResponse resp = (HttpServletResponse) FacesContext
					.getCurrentInstance().getExternalContext().getResponse();
			//TODO: return an HTTP 404 if content is null;
			String docTitle = (String) docToStream.getTitle();
			byte[] docContent = docToStream.getContent();
			try {
				FileUtility.streamReportToBrowser(resp, docTitle, docContent);
			} catch (IOException e) {
				LOG.error("Error in CaseDetailPage.viewFile() method: " + e);
			}
			context.responseComplete();
		} else {
			LOG.debug("Error: Documents Contents Null, not able to be viewed.");
		}
		// TODO Need to add error message informing user of error state
	}
	

	public UIParameter getDocumentClicked_Imported() {
		return this.documentClicked_Imported;
	}


	public UIParameter getDocumentClicked_Uploaded() {
		return this.documentClicked_Uploaded;
	}


	/**
	 * Getter for the property documentList
	 * 
	 * @return List<Documents>
	 */
	public List<Documents> getDocumentList() {
		return documentList;
	}

	/**
	 * Setter for the property documentList
	 * 
	 * @param documentList
	 */
	public void setDocumentList(List<Documents> documentList) {
		this.documentList = documentList;
	}

	/**
	 * @return Returns the caseRecordUuid.
	 */
	public String getCaseRecordUuid() {
		return caseRecordUuid;
	}

	/**
	 * @param caseRecordUuid
	 *            The caseRecordUuid to set.
	 */
	public void setCaseRecordUuid(String caseRecordUuid) {
		this.caseRecordUuid = caseRecordUuid;
	}

	/**
	 * @return the renderSignedText
	 */
	public boolean isRenderSignedText() {
		return renderSignedText;
	}

	/**
	 * @param renderSignedText
	 *            the renderSignedText to set
	 */
	public void setRenderSignedText(boolean renderSignedText) {
		this.renderSignedText = renderSignedText;
	}

	/**
	 * This method gets invoked when user clicks the validate document button on
	 * the caseDetails page.
	 * 
	 * @return String
	 */
	public String gotoValidateDocument() {
		Documents doc = (Documents) this.getValidateBinding().getValue();
		/*
		 * If the document is of pdf type
		 */
		if (doc.getPhysicalType().equalsIgnoreCase("pdf")) {
			this.setValidCourtSeal(this.validatePDFCourtSeal(doc));
		}
		/*
		 * If the document is of xml type document
		 */
		if (doc.getPhysicalType().equalsIgnoreCase("xml")) {
			this.setValidCourtSeal(this.validateXMLCourtSeal(doc));
		}
		return "gotoValidateScreenPage";
	}

	/**
	 * @return the organizationName
	 */
	public String getOrganizationName() {
		return organizationName;
	}

	/**
	 * @param organizationName
	 *            sets the organizationName
	 */
	public void setOrganizationName(String organizationName) {
		this.organizationName = organizationName;
	}

	/**
	 * This is the helper method to validate the court seal of the PDF document
	 * 
	 * @param doc
	 * @return
	 */
	private boolean validatePDFCourtSeal(Documents doc) {
		boolean valid = false;
		CourtSeal cs = (CourtSeal) doc.getCourtSeal();
		byte[] courtSealValue = cs.getCourtSealValue();
		byte[] certificateChain = cs.getCertificateChain();
		SignatureValidator sigVal = new SignatureValidator();
		valid = sigVal.validate(doc.getContent(), courtSealValue,
				certificateChain);
		return valid;
	}

	/**
	 * This is the helper method to validate the court seal of the XML document.
	 * 
	 * @param doc
	 * @return
	 */
	private boolean validateXMLCourtSeal(Documents doc) {
		boolean valid = false;
		CourtSeal cs = (CourtSeal) doc.getCourtSeal();
		byte[] courtSealValue = cs.getCourtSealValue();
		byte[] certificateChain = cs.getCertificateChain();
		SignatureValidator sigVal = new SignatureValidator();
		valid = sigVal.validate(doc.getContent(), courtSealValue,
				certificateChain);
		return valid;
	}

	/**
	 * @return the validateBinding
	 */
	public UIParameter getValidateBinding() {
		return validateBinding;
	}

	/**
	 * @param validateBinding
	 *            the validateBinding to set
	 */
	public void setValidateBinding(UIParameter validateBinding) {
		this.validateBinding = validateBinding;
	}

	/**
	 * @return the bindDocument
	 */
	public Documents getBindDocument() {
		return bindDocument;
	}

	/**
	 * @param bindDocument
	 *            the bindDocument to set
	 */
	public void setBindDocument(Documents bindDocument) {
		this.bindDocument = bindDocument;
	}

	/**
	 * @return the validCourtSeal
	 */
	public boolean isValidCourtSeal() {
		return validCourtSeal;
	}

	/**
	 * @param validCourtSeal
	 *            the validCourtSeal to set
	 */
	public void setValidCourtSeal(boolean validCourtSeal) {
		this.validCourtSeal = validCourtSeal;
	}

	/**
	 * This method is get called when user press the sign button to sign PDF or
	 * XML document
	 * 
	 * @return String
	 * @throws Exception
	 */
	public String signDocument() throws Exception {

		/*
		This was some testing code. Nothing to see here =).
				Documents doc = (Documents) this.getSignatureBinding().getValue();
				Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
				sessionMap.put("documentUuid", doc.getUuid());
				return DocumentSigningFactory.signDocumentNavigation(doc);
		*/
		
		Map<String, Object> sessionMap = this.getSessionMap();
		Person personSigner = (Person)sessionMap.get("person");
		Documents doc = (Documents) this.getSignatureBinding().getValue();
		Court c = this.getCaseRecord().getCourt();
		if(c.isVisualSignEnabled()) {
			
			sessionMap.put("documentUuid",((Documents)this.signatureBinding.getValue()).getUuid());
			return "sign";
		}
		
		return SynchronizedClerkSign.signDocument(this);
	}
	
	/**
	 * This is the synchronized sign button action.
	 * It is synchronized across the entire system.
	 * TODO: synchronize it across /one/ court only.
	 * @author artripa
	 *
	 */
	public static class SynchronizedClerkSign {

		public static synchronized String signDocument(CaseDetailsPage page) throws Exception
		{
			
	
			//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().commit();	
			//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().begin();	
			//Reload the data in this synchronization.
			page.loadData();
			Documents doc = (Documents) page.getSignatureBinding().getValue();
			String caseUuid = page.getCaseRecord().getUuid();
			List<Documents> pdfList = page.getModelFacade().getPDFDocuments(caseUuid);
			List<Documents> uDoc = new java.util.LinkedList();
	        //added by Michael A to get the list of pdf's signed by both the attorney and the clerk or not, to display 
			for (Documents document : pdfList) {
				int docStatusCode = document.getStatus().getCode();
				if (docStatusCode == 2) {			//imported docu
				} else if (docStatusCode != 2) {
					uDoc.add(document);
				}
			}
			Person personSigned = (Person) page.getFacesContext()
			.getExternalContext().getSessionMap().get("person");
			boolean docOrder = false;
			boolean docSigned = false;
			// Frank added the following block
			for (Documents docx : uDoc) {
				
				docOrder = page.digitalSignerController.isDocumentOrderForClerk(docx);
				docSigned = page.digitalSignerController.isDocumentSignedForClerk(docx, personSigned);
				if (docOrder) {
					docx.setOrderedDoc(true);
					if (docSigned) {
						//this.renderSignedText = true;
						//this.renderSignButton = false;
						docx.setSignedDoc(true);
						if(doc.getUuid().equalsIgnoreCase(docx.getUuid()))
						{
							System.out.println("[SYNCH] ALREADY SIGNED");
							FacesContext.getCurrentInstance().addMessage("facesMessage", 
										new FacesMessage("Case Being worked on by another user!")
							);
							return "";
						}						
					} else {
						//this.renderSignedText = false;
						//this.renderSignButton = true;
						docx.setSignedDoc(false);
					}
				}else{
					docx.setOrderedDoc(false);
				}
			}

			

			
			System.out.println("Checking isSIgned...");
			boolean isSigned = page.digitalSignerController.isDocumentSignedForClerk(doc, personSigned);
			System.out.println("-----------------");
			
			/*
			System.out.println(
					String.format("[SYNCHRONIZED] signDocument starting! %s uuid: %s signed: %s",
							((Documents)page.getSignatureBinding().getValue()).getUuid(),
							Boolean.toString(isSigned),
							DateFormat.getDateInstance().format(new Date())));
							
							*/
			
			if(isSigned) return ""; //TODO: throw FacesMessage
			

			//save original document content in case signature failed
			byte[] originalDocContent = doc.getContent();
			
			byte[] sigInByte = null;
			
			Map sessionMap = page.getFacesContext().getExternalContext().getSessionMap();
			// Retrieve Person from the session
			Person personSigner = (Person) sessionMap.get("person");
			String clerkRoleUuid = "uuid2"; // The Clerk Role UUID
			
			// Retrieve the certificate password
			//LdapDirectoryPerson ldPerson = page.getModelFacade().findLdapDirectoryByPerson(personSigner);	
			
			// Add visual signature first
		//	page.pdfStamperController.addVisualSignatureOnDocument(doc,personSigner,ldPerson,clerkRoleUuid);
			page.pdfStamperController.addVisualSignatureOnDocument(doc,personSigner,clerkRoleUuid);
			// If visual Signature is successfully put on the document then digitally sign
			if(page.pdfStamperController.isSignedDoc() == true) {
			//	sigInByte = page.digitalSignerController.signDocument(doc, personSigner,clerkRoleUuid,ldPerson);
				sigInByte = page.digitalSignerController.signDocument(doc, personSigner,clerkRoleUuid);
				//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().commit();
				//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().begin();
				
				// update the signed field in the documents object
				DocumentStatus documentStatus  = new DocumentStatus();
				if(page.digitalSignerController.isSignedDoc() == true) {
					int statusCode = 8;			//signedByClerk
					documentStatus = page.getModelFacade().findDocumentStatus(statusCode);
					//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().begin();
					page.digitalSignerController.updateDatabaseAfterSigned(doc, documentStatus, personSigner, sigInByte);
					//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().commit();
				}
				// update the signed field in the documents object
				doc.setSignedDoc(page.digitalSignerController.isSignedDoc());
				// for rendering purpose in the xhtml page set the field ordered as false
				doc.setOrderedDoc(page.digitalSignerController.isOrderedDoc());
			}
				
			//Check the status of the doc and if it is 
			//failedClerkSignature for the clerk then set the corresponding booleans
			//that cause the message to appear on the page indicating the documents
			//with the problem and also for the sign command to reappear
			
			//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().begin();
			if (doc.getContent() == null){
				doc.setContent(null,originalDocContent);
				page.renderRejectButton = true;
				page.docNoContentsMessage = true;
				sessionMap.put("clerkCaseDatailsPage", page);
				CaseRecordHistory crh = new CaseRecordHistory();
				crh.setCaseRecord(page.caseRecord);
				crh.setEventDateTime(DateUtil.getCurrentDate());
				crh.setPerson(personSigner);
				// b7006e6c-695c-11dd-945f-00301b45ff56
				//HibernatePhaseListener.getSessionFactory().getCurrentSession()
				//		.getTransaction().begin();
				crh.setEventType(page.getModelFacade().findCaseRecordEventType(19));
				page.getModelFacade().insertCaseRecordHistory(crh);
				//HibernatePhaseListener.getSessionFactory().getCurrentSession()
				//		.getTransaction().commit();
			} else if(doc.getStatus().getCode() == 14) {
				//Clerk signature failure not necessarily from no contents
				page.renderRejectButton = true;
				page.signatureFailedMessage = true;
				sessionMap.put("clerkCaseDatailsPage", page);
				CaseRecordHistory crh = new CaseRecordHistory();
				crh.setCaseRecord(page.caseRecord);
				crh.setEventDateTime(DateUtil.getCurrentDate());
				crh.setPerson(personSigner);
				// b7006e6c-695c-11dd-945f-00301b45ff56
				//HibernatePhaseListener.getSessionFactory().getCurrentSession()
				//		.getTransaction().begin();
				crh.setEventType(page.getModelFacade().findCaseRecordEventType(19));
				page.getModelFacade().insertCaseRecordHistory(crh);
				//HibernatePhaseListener.getSessionFactory().getCurrentSession()
				//		.getTransaction().commit();

			}
			
			page.loadData();
			
			
			//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().commit();
			
			System.out.println(
				String.format("[SYNCHRONIZED] signDocument ending! %s",
					DateFormat.getDateInstance().format(new Date())));
		
			return "stayWithRedirect";
		}
	}
	
	
	
	
	public void signDocument(Documents doc) throws Exception {
		
		Map<String, Object> sessionMap = this.getSessionMap();
		Person personSigner = (Person)sessionMap.get("person");	
		Court c = this.getCaseRecord().getCourt();
		CaseRecord cr = this.getCaseRecord();
		
		byte[] originalDocContent = doc.getContent();
		
		String clerkRoleUuid = "uuid2"; // The Clerk Role UUID
		DocumentStatus documentStatus  = new DocumentStatus();
		int statusCode = 8;			//signedByClerk
		
		if(doc.getContent()!=null){
		
		pdfStamperController.addVisualSignatureOnDocument(doc,personSigner,clerkRoleUuid);
		loadData();
		documentStatus = this.getModelFacade().findDocumentStatus(statusCode);
		this.getModelFacade().updateDocumentStatus(doc.getUuid(), documentStatus);
		CaseRecordHistory crh = new CaseRecordHistory();
		crh.setCaseRecord(caseRecord);
		crh.setEventDateTime(DateUtil.getCurrentDate());
		crh.setPerson(personSigner);
		crh.setEventType(this.getModelFacade().findCaseRecordEventType(17));
		this.getModelFacade().insertCaseRecordHistory(crh);
		
		}else{
			
			CaseRecordHistory crh = new CaseRecordHistory();
			crh.setCaseRecord(caseRecord);
			crh.setEventDateTime(DateUtil.getCurrentDate());
			crh.setPerson(personSigner);
			crh.setEventType(this.getModelFacade().findCaseRecordEventType(19));
			this.getModelFacade().insertCaseRecordHistory(crh);
			
		}

		loadData();
	}
	
	

	public UIParameter getSignatureBinding() {
		return signatureBinding;
	}

	public boolean isRenderSignButton() {
		return renderSignButton;
	}

	public void setRenderSignButton(boolean renderSignButton) {
		this.renderSignButton = renderSignButton;
	}

	public void setSignatureBinding(UIParameter signatureBinding) {
		this.signatureBinding = signatureBinding;
	}

	public String viewSignatureDetails() throws Exception {
		return "viewSignatureDetails";
	}

	/**
	 * @return Returns the signatures list.
	 */
	public DataModel getSignaturesListModel() {
		return signaturesListModel;
	}

	/**
	 * @param sets
	 *            the signatures list.
	 */
	public void setSignaturesListModel(DataModel signaturesListModel) {
		this.signaturesListModel = signaturesListModel;
	}

	/**
	 * @return the signaturesList
	 */
	public List<Signatures> getSignaturesList() {
		return signaturesList;
	}

	/**
	 * @param sets
	 *            signaturesList
	 */
	public void setSignaturesList(List<Signatures> signaturesList) {
		this.signaturesList = signaturesList;
	}

	/**
	 * @return Returns the sigantureCounterPerSignerModel.
	 */
	public DataModel getSigantureCounterPerSignerModel() {
		return sigantureCounterPerSignerModel;
	}

	/**
	 * @param sets
	 *            the sigantureCounterPerSignerModel.
	 */
	public void setSigantureCounterPerSignerModel(
			DataModel sigantureCounterPerSignerModel) {
		this.sigantureCounterPerSignerModel = sigantureCounterPerSignerModel;
	}

	/**
	 * @return Returns the signatureCounterModel.
	 */
	public DataModel getSignatureCounterModel() {
		return signatureCounterModel;
	}

	/**
	 * @param sets
	 *            the signatureCounterModel.
	 */
	public void setSignatureCounterModel(DataModel signatureCounterModel) {
		this.signatureCounterModel = signatureCounterModel;
	}

	/**
	 * @return Returns a docSignedByThisPerson
	 */
	public Documents getDocSignedByThisPerson() {
		return docSignedByThisPerson;
	}

	/**
	 * @param sets
	 *            a docSignedByThisPerson.
	 */
	public void setDocSignedByThisPerson(Documents docSignedByThisPerson) {
		this.docSignedByThisPerson = docSignedByThisPerson;
	}

	/*
	 * @return Returns the signatureCounter.
	 */
	public Counter getSignatureCounter() {
		return signatureCounter;
	}

	/**
	 * @param sets
	 *            the signatureCounter.
	 */
	public void setSignatureCounter(Counter signatureCounter) {
		this.signatureCounter = signatureCounter;
	}

	public String getSignatureConfTrackNumber() {
		return signatureConfTrackNumber;
	}

	public void setSignatureConfTrackNumber(String signatureConfTrackNumber) {
		this.signatureConfTrackNumber = signatureConfTrackNumber;
	}

	public CounterPerSigner getSignatureCounterPerSigner() {
		return signatureCounterPerSigner;
	}

	public void setSignatureCounterPerSigner(
			CounterPerSigner signatureCounterPerSigner) {
		this.signatureCounterPerSigner = signatureCounterPerSigner;
	}

	public String getSignatureTrackingID() {
		return signatureTrackingID;
	}

	public void setSignatureTrackingID(String signatureTrackingID) {
		this.signatureTrackingID = signatureTrackingID;
	}

	public Documents getSignedDocument() {
		return signedDocument;
	}

	public void setSignedDocument(Documents signedDocument) {
		this.signedDocument = signedDocument;
	}

	/**
	 * @return the jurisdiction
	 */
	public String getJurisdiction() {
		return jurisdiction;
	}

	/**
	 * @param jurisdiction
	 *            the jurisdiction to set
	 */
	public void setJurisdiction(String jurisdiction) {
		this.jurisdiction = jurisdiction;
	}

	/**
	 * @return the importedDocumentList
	 */
	public List<Documents> getImportedDocumentsList() {
		return importedDocumentsList;
	}

	/**
	 * @param importedDocumentList
	 *            the importedDocumentList to set
	 */
	public void setImportedDocumentsList(List<Documents> importedDocumentList) {
		this.importedDocumentsList = importedDocumentList;
	}

	/**
	 * @return the importedDocumentsModel
	 */
	public DataModel getImportedDocumentsModel() {
		reload();
		return importedDocumentsModel;
	}

	/**
	 * @param importedDocumentsModel
	 *            the importedDocumentsModel to set
	 */
	public void setImportedDocumentsModel(DataModel importedDocumentsModel) {
		this.importedDocumentsModel = importedDocumentsModel;
	}

	/**
	 * @return the uploadedDocumentsList
	 */
	public List<Documents> getUploadedDocumentsList() {
		return uploadedDocumentsList;
	}

	/**
	 * @param uploadedDocumentsList
	 *            the uploadedDocumentsList to set
	 */
	public void setUploadedDocumentsList(List<Documents> uploadedDocumentsList) {
		this.uploadedDocumentsList = uploadedDocumentsList;
	}

	/**
	 * @return the uploadedDocumentsModel
	 */
	public DataModel getUploadedDocumentsModel() {
		reload();
		return uploadedDocumentsModel;
	}

	private void reload() {
		Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
		String caseUuid = (String) sessionMap.get("caseUuid");
		List<Documents> pdfList = new ArrayList<Documents>();
		List<Documents>iDocs = new ArrayList<Documents>();
		List<Documents>eDocs = new ArrayList<Documents>();
		
		pdfList = this.getModelFacade().getPDFDocuments(caseUuid);
		
		for(Documents document : pdfList) {
			int docStatusCode = document.getStatus().getCode();
			if(docStatusCode == Constants.DocumentStatus.IMPORTED) 
			{
				iDocs.add(document);
			} 
			else 
			{
				eDocs.add(document);
			}
		}
		
		this.setImportedDocumentsList(iDocs);
		this.setUploadedDocumentsList(eDocs);
		this.setDocumentList(pdfList);
		if(importedDocumentsModel==null)
			importedDocumentsModel = new ListDataModel();
		if(uploadedDocumentsModel==null)
			uploadedDocumentsModel =  new ListDataModel();
		
		importedDocumentsModel.setWrappedData(this.getImportedDocumentsList());
		uploadedDocumentsModel.setWrappedData(this.getUploadedDocumentsList());
		
	}


	/**
	 * @param uploadedDocumentsModel
	 *            the uploadedDocumentsModel to set
	 */
	public void setUploadedDocumentsModel(DataModel uploadedDocumentsModel) {
		this.uploadedDocumentsModel = uploadedDocumentsModel;
	}

	/**
	 * Helper method to check whether a document is signed by the given person
	 * 
	 * @param docs
	 * @param person
	 * @return
	 */
	private boolean isDocumentSigned(Documents doc, Person person) {
		boolean documentsSigned = false;
		boolean ordered = false;
		List<Documents> orderedDocs = new ArrayList<Documents>();
		
		String courtUuid = (String)this.getFacesContext().getExternalContext().getSessionMap().get("courtUuid");
		
		if(!digitalSignerController.isDocumentOrderForClerk(doc)) return true;
		
			List<Signatures> docSignatures = doc.getSignatures();
			documentsSigned = false;
			for (Signatures s : docSignatures) {
				Person personSigned = s.getSignedByPerson();
				System.out.println("Signed Person Uuid "
						+ personSigned.getUuid());
				System.out.println("Parameter passes Person Uuid "
						+ person.getUuid());
				if (personSigned.getUuid().equals(person.getUuid())) {
					documentsSigned = true;
					break;
				}
				//break;
			}
			if (!documentsSigned) {
				//this.setRenderImportButton(false);
				return false;
			}
			return documentsSigned;
		}
	
	
	
	/**
	 * Helper method to check whether all documents which are to be signed by
	 * clerk are signed or not.
	 * 
	 * @param docs
	 * @param person
	 * @return
	 */
	private boolean isAllDocumentsSigned(List<Documents> docs, Person person) {
		boolean documentsSigned = false;
		boolean ordered = false;
		List<Documents> orderedDocs = new ArrayList<Documents>();
		
		String courtUuid = (String)this.getFacesContext().getExternalContext().getSessionMap().get("courtUuid");
		
		for (Documents d : docs) {
			ordered = digitalSignerController.isDocumentOrderForClerk(d);
			if (ordered) {
				orderedDocs.add(d);
			}
		}
		List<Signatures> docSignatures = new ArrayList<Signatures>();
		if(!orderedDocs.isEmpty()) {
			for (Documents oDoc : orderedDocs) {
				docSignatures = oDoc.getSignatures();
				documentsSigned = false;
				for (Signatures s : docSignatures) {
					Person personSigned = s.getSignedByPerson();
					System.out.println("Signed Person Uuid "
							+ personSigned.getUuid());
					System.out.println("Parameter passes Person Uuid "
							+ person.getUuid());
							
					//TODO: check Roles of user
					if (personSigned.getUuid().equals(person.getUuid())) {
						documentsSigned = true;
						break;
					}
					//break;
				}
				if (!documentsSigned) {
					this.setRenderImportButton(false);
					break;
				}
			}
		} else {
			documentsSigned = true;
		}

		return documentsSigned;
	}

	/**
	 * This method checks whether all documents are signed or not.
	 * If all documents are signed then change the caseRecord status and 
	 * insert the event into the caseRecordHistory table
	 * @param docs : which document
	 * @param person : who signed
	 */
	private void updateDatabaseAfterAllSigned(List<Documents> docs,
			Person person) {
		String courtUuid = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("courtUuid");
		boolean signedByClerk = false;
		for (Documents doc : docs) {
			if (doc.getStatus().getCode() == 8) {
				signedByClerk = true;
			}
		}
		if (this.isAllDocumentsSigned(docs, person) && signedByClerk == true) {
			this.getModelFacade().updateCaseRecordStatus(
					this.getCaseRecord().getUuid(),
					new CaseRecordStatus(20, "ReadyToImport"), courtUuid);
			this.setRenderImportButton(true);
			this.setRenderRejectButton(true);
			//the signature is a success 
			// Insert event into the CaseRecord History table
			CaseRecordHistory crh = new CaseRecordHistory();
			crh.setCaseRecord(caseRecord);
			crh.setEventDateTime(DateUtil.getCurrentDate());
			crh.setPerson(person);
			crh.setEventType(this.getModelFacade().findCaseRecordEventType(17));
			this.getModelFacade().insertCaseRecordHistory(crh);
		}
	}

	public boolean isDocNoContentsMessage() {
		return docNoContentsMessage;
	}

	public void setDocNoContentsMessage(boolean docNoContentsMessage) {
		this.docNoContentsMessage = docNoContentsMessage;
	}

	public boolean isSignatureFailedMessage() {
		return signatureFailedMessage;
	}

	public void setSignatureFailedMessage(boolean signatureFailedMessage) {
		this.signatureFailedMessage = signatureFailedMessage;
	}

	public boolean isSignatureFailed() {
		return signatureFailed;
	}

	public void setSignatureFailed(boolean signatureFailed) {
		this.signatureFailed = signatureFailed;
	}

	public boolean isRenderSignatureFailureMessage() {
		return renderSignatureFailureMessage;
	}

	public void setRenderSignatureFailureMessage(
			boolean renderSignatureFailureMessage) {
		this.renderSignatureFailureMessage = renderSignatureFailureMessage;
	}

	/**
	 * This method navigates the user to a page from which the user
	 * has the options to stamp a document with either a court received stamp 
	 * or the docket id stamp
	 */
	public String goToOperationsApplyCourtStampPage(){
		return "goToOperationsApplyCourtStampPage";
	}
	/**
	 * This method navigates the user to a page from which the user
	 * has can stamp a document with the docket id stamp
	 */
	public String goToOperationsApplyDocketIdStampPage(){
		return "goToOperationsApplyDocketIdStampPage";
	}

	public boolean isRenderApplyCourtReceivedStampdButton() {
		return renderApplyCourtReceivedStampdButton;
	}

	public void setRenderApplyCourtReceivedStampdButton(
			boolean renderApplyCourtReceivedStampdButton) {
		this.renderApplyCourtReceivedStampdButton = renderApplyCourtReceivedStampdButton;
	}

	public boolean isRenderApplyDocketIdStampdButton() {
		return renderApplyDocketIdStampdButton;
	}

	public void setRenderApplyDocketIdStampdButton(
			boolean renderApplyDocketIdStampdButton) {
		this.renderApplyDocketIdStampdButton = renderApplyDocketIdStampdButton;
	}

	public String getOCSSCaseNumber() {
		return OCSSCaseNumber;
	}

	public void setOCSSCaseNumber(String caseNumber) {
		OCSSCaseNumber = caseNumber;
	}

	public String getCourtCaseNumber() {
		return courtCaseNumber;
	}

	public void setCourtCaseNumber(String courtCaseNumber) {
		this.courtCaseNumber = courtCaseNumber;
	}
	
	public void setRenderFileNewDocuments(boolean renderFileNewDocuments) {
		this.renderFileNewDocuments = renderFileNewDocuments;
	}


	public void setRenderCaseMetaData(boolean renderCaseMetaData) {
		this.renderCaseMetaData = renderCaseMetaData;
	}


	public boolean isRenderCaseMetaData() {
		return renderCaseMetaData;
	}


	public void setCourtRoom(String courtRoom) {
		this.courtRoom = courtRoom;
	}


	public String getCourtRoom() {
		return courtRoom;
	}


	public void setCourtTime(String courtTime) {
		this.courtTime = courtTime;
	}


	public String getCourtTime() {
		return courtTime;
	}


	public void setRenderSetCourtDate(boolean renderSetCourtDate) {
		this.renderSetCourtDate = renderSetCourtDate;
	}


	public boolean isRenderSetCourtDate() {
		return renderSetCourtDate;
	}


	public boolean isRenderRejectReasonButton() {
		return renderRejectReasonButton;
	}


	public void setRenderRejectReasonButton(boolean renderRejectReasonButton) {
		this.renderRejectReasonButton = renderRejectReasonButton;
	}
	
	public void onCaseUuidChange(String caseUuid){
		Map sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();	 	
	 	sessionMap.put("caseUuid", caseUuid);
	 	sessionMap.put("from", "trashcanPage");	 
	 	this.loadData();
	 }
	
	
}